package top.hcode.hoj.service.admin.course;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.hcode.hoj.dao.LinkLoader;
import top.hcode.hoj.dao.common.FileEntityService;
import top.hcode.hoj.dao.common.FilePreviewDao;
import top.hcode.hoj.dao.course.CourseSectionDao;
import top.hcode.hoj.dao.course.LessonDao;
import top.hcode.hoj.manager.file.PPTPreviewManager;
import top.hcode.hoj.mapper.CourseMapper;
import top.hcode.hoj.pojo.dto.AdminQueryCourseSectionDTO;
import top.hcode.hoj.pojo.dto.CourseSectionSortDTO;
import top.hcode.hoj.pojo.entity.common.FilePreview;
import top.hcode.hoj.pojo.entity.course.Course;
import top.hcode.hoj.pojo.entity.course.CourseSection;
import top.hcode.hoj.pojo.vo.CourseSectionVO;
import top.hcode.hoj.utils.HttpUtils;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * @author orangej
 * @since 2024/12/18
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AdminCourseSectionService {


    private final CourseSectionDao sectionDao;

    private final CourseMapper courseMapper;

    private final LessonDao lessonDao;

    private final LinkLoader cascadeLoader;

    private final FileEntityService fileEntityService;

    private final PPTPreviewManager pptPreviewManager;

    private final FilePreviewDao filePreviewDao;


    public IPage<CourseSection> getCourseSectionList(AdminQueryCourseSectionDTO dto) {
        IPage<CourseSection> pager = new Page<>(dto.getCurrentPage(), dto.getLimit());

        QueryWrapper<CourseSection> query = Wrappers.query();
        if (dto.getCourseId() != null) {
            query.eq("course_id", dto.getCourseId());
        }
        if (Strings.isNotBlank(dto.getKeyword())) {
            query.like("section_name", dto.getKeyword());
        }
        query.orderByAsc("course_id", "sort_order");

        pager = sectionDao.page(pager, query);
        cascadeLoader.loadCourse(pager.getRecords());
        return pager;
    }

    @Transactional
    public CourseSection saveCourseSection(CourseSection section) {
        boolean isCreate = false;
        if (section.getId() == null) {
            isCreate = true;

            // 新增
            Validator.validateNotNull(section.getCourseId(), "课程不能为空");
            Course course = courseMapper.selectById(section.getCourseId());
            section.setUid(course.getUid());
            section.setGid(course.getGid());

            // 设置排序
            if (section.getSortOrder() == null || section.getSortOrder() == 0) {
                section.setSortOrder(sectionDao.getNextSortOrder(section.getCourseId()));
            }


        }

        sectionDao.saveOrUpdate(section);

        // ppt预览
        if (isCreate && "ppt".equalsIgnoreCase(section.getFileType())) {
            pptPreviewManager.generateCoursePPTPreviewImage(section.getId(), section.getFileUrl());
        }

        return section;
    }

    public CourseSectionVO getSectionDetail(Long id) {
        CourseSection section = sectionDao.getById(id);
        CourseSectionVO vo = new CourseSectionVO();
        Lang.copyProperties(section, vo);

        if ("ppt".equalsIgnoreCase(section.getFileType())) {
            FilePreview preview = filePreviewDao.getBySourceFileUrl(section.getFileUrl());
            if (preview != null) {
                String firstUrl = preview.getPreviewUrl();
                String urlBase = StrUtil.subBefore(firstUrl, "/", true);
                List<String> urlList = new LinkedList<>();
                for (int i = 0; i < preview.getPageNum(); i++) {
                    String url = urlBase + "/" + (i + 1) + ".jpeg";
                    urlList.add(url);
                }
                vo.setPreviewImageList(urlList);
            }
        } else if ("md".equalsIgnoreCase(section.getFileType())) {
            String content = HttpUtils.downloadFileContent(section.getFileUrl());
            vo.setPreviewContent(content);
        }

        return vo;
    }

    @Transactional
    public void deleteCourseSection(Long id) {
        CourseSection section = sectionDao.getById(id);
        deleteCourseSection(section);
    }

    @Transactional
    public void deleteCourseSection(CourseSection section) {
        if (section == null) return;

        // 删除文件
        String fileUrl = section.getFileUrl();
        if (Strings.isNotBlank(fileUrl)) {
            fileEntityService.updateFileToDeleteByFilePath(fileUrl);
        }

        // delete
        sectionDao.removeById(section.getId());

        // delete children
        List<CourseSection> children = sectionDao.listChildrenOf(section.getId());
        if (children != null && !children.isEmpty()) {
            for (CourseSection child : children) {
                deleteCourseSection(child);
            }
        }
    }

    /**
     * 更新指定节点的 order 和 parentId
     */
    @Transactional
    public void saveCourseSectionSort(CourseSectionSortDTO dto) {
        Long parentId = dto.getParentId();
        if (parentId != null && parentId <= 0) parentId = null;

        List<Long> idList = dto.getIdList();
        if (idList == null || idList.isEmpty()) return;

        for (int i = 0; i < idList.size(); i++) {
            Long id = idList.get(i);
            int sort = i + 1;

            UpdateWrapper<CourseSection> update = new UpdateWrapper<>();
            update.eq("id", id)
                    .set("sort_order", sort)
                    .set("parent_id", parentId)
                    .set("gmt_modified", new Date());
            sectionDao.update(update);
        }
    }
}
